import { typescriptOfSchema } from '@tgriesser/schemats'
import { format } from 'prettier'
import path from 'path'
import fs from 'fs-extra'
import _ from 'lodash'
import Knex from 'knex'

const config = require('../config.development.json')

const knex = Knex({
  ...config.database,
})

const GENERATED_DIR = path.join(__dirname, '..', 'src', 'generated')
const OUT_TYPES = path.join(GENERATED_DIR, 'ghost-db-types.ts')
const OUT_TABLES = path.join(GENERATED_DIR, 'ghost-db-tables.ts')

async function generateTypes() {
  const rows = await knex
    .select('*')
    .from('information_schema.tables')
    .where('table_schema', config.database.connection.database)
  const tableNames = _.map(rows, 'TABLE_NAME').sort()
  const connectionString = dbConnectionString()
  await knex.destroy()
  console.log(`Reading from: ${connectionString}`)
  const prettierConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '../../../.prettierrc'), 'utf8'))
  const contents = await typescriptOfSchema(connectionString, tableNames, null, {
    writeHeader: false,
    camelCase: true,
    prettier: true,
    prettierConfig,
  })
  await fs.writeFile(OUT_TYPES, format(contents, { ...prettierConfig, parser: 'typescript' }))
  const tableRows = tableNames.reduce((result: string[], tbl) => {
    return result.concat(`${_.camelCase(tbl)}: dbt.${_.upperFirst(_.camelCase(tbl))};`)
  }, [])
  await fs.writeFile(
    OUT_TABLES,
    format(
      `
      /* Auto generated by ${__filename.replace(__dirname, '')} */
      import * as dbt from './ghost-db-types';

      export interface DBTables {
        ${tableRows.join('\n')}
      }

      export type DBTableName = Extract<keyof DBTables, string>;
    `,
      {
        ...prettierConfig,
        parser: 'typescript',
      }
    )
  )
}

function dbConnectionString() {
  const {
    database: {
      client,
      connection: { host, port, user, password, database },
    },
  } = require('../config.development.json')
  return `${client}://${user}:${password}@${host}:${port}/${database}`
}

generateTypes()
  .then(() => {
    console.log('Types generated.')
    process.exit()
  })
  .catch((e) => {
    console.error('mysql must be running to run ghost example')
    process.exit(1)
  })
